_require local "../../../libs/env/main/SEnv.smi"
_require local "../../../libs/env/main/SSet.smi"
(* _require local "../../../extensions/debug/main/Bug.smi" *)

_require "../../../../basis.smi"
_require "../../../../smlformat-lib.smi"
_require local "../../../../smlnj-lib/Util/ord-key-sig.sml"
_require local "../../../../smlnj-lib/Util/ord-set-sig.sml"
_require local "../../../../smlnj-lib/Util/ord-map-sig.sml"
_require "../../../data/symbols/main/Symbol.smi"
_require local "./NameMangle.smi"

structure ExternSymbol =
struct

  type id (= string)
  val touch : Symbol.longsymbol -> id
  val toString : id -> string
  val format_id : id -> SMLFormat.FormatExpression.expression list

  structure Map =
  struct
    structure Key =
    struct
      type ord_key = id
      val compare : ord_key * ord_key -> order
    end
    type 'a map (= boxed)
    val empty : 'a map
    val isEmpty : 'a map -> bool
    val singleton : Key.ord_key * 'a -> 'a map
    val insert : 'a map * Key.ord_key * 'a -> 'a map
    val insert' : (Key.ord_key * 'a) * 'a map -> 'a map
    val find : 'a map * Key.ord_key -> 'a option
    val lookup : 'a map * Key.ord_key -> 'a
    val inDomain : 'a map * Key.ord_key -> bool
    val remove : 'a map * Key.ord_key -> 'a map * 'a
    val first : 'a map -> 'a option
    val firsti : 'a map -> (Key.ord_key * 'a) option
    val numItems : 'a map -> int
    val listItems : 'a map -> 'a list
    val listItemsi : 'a map -> (Key.ord_key * 'a) list
    val listKeys : 'a map -> Key.ord_key list
    val collate : ('a * 'a -> order) -> 'a map * 'a map -> order
    val unionWith : ('a * 'a -> 'a) -> 'a map * 'a map -> 'a map
    val unionWithi : (Key.ord_key * 'a * 'a -> 'a) -> 'a map * 'a map -> 'a map
    val intersectWith : ('a * 'b -> 'c) -> 'a map * 'b map -> 'c map
    val intersectWithi : (Key.ord_key * 'a * 'b -> 'c) -> 'a map * 'b map -> 'c map
    val mergeWith : ('a option * 'b option -> 'c option) -> 'a map * 'b map -> 'c map
    val mergeWithi : (Key.ord_key * 'a option * 'b option -> 'c option) -> 'a map * 'b map -> 'c map
    val app : ('a -> unit) -> 'a map -> unit
    val appi : (Key.ord_key * 'a -> unit) -> 'a map -> unit
    val map : ('a -> 'b) -> 'a map -> 'b map
    val mapi : (Key.ord_key * 'a -> 'b) -> 'a map -> 'b map
    val foldl : ('a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val foldli : (Key.ord_key * 'a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val foldr : ('a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val foldri : (Key.ord_key * 'a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val filter : ('a -> bool) -> 'a map -> 'a map
    val filteri : (Key.ord_key * 'a -> bool) -> 'a map -> 'a map
    val mapPartial : ('a -> 'b option) -> 'a map -> 'b map
    val mapPartiali : (Key.ord_key * 'a -> 'b option) -> 'a map -> 'b map
  end

  structure Set =
  struct
    structure Key =
    struct
      type ord_key = id
      val compare : ord_key * ord_key -> order
    end
    type item = Key.ord_key
    type set (= boxed)
    val empty : set
    val singleton : item -> set
    val fromList : item list -> set
    val add : set * item -> set
    val add' : item * set -> set
    val addList : set * item list -> set
    val delete : set * item -> set
    val member : set * item -> bool
    val isEmpty : set -> bool
    val equal : set * set -> bool
    val compare : set * set -> order
    val isSubset : set * set -> bool
    val numItems : set ->  int
    val listItems : set -> item list
    val union : set * set -> set
    val intersection : set * set -> set
    val difference : set * set -> set
    val map : (item -> item) -> set -> set
    val app : (item -> unit) -> set -> unit
    val foldl : (item * 'a -> 'a) -> 'a -> set -> 'a
    val foldr : (item * 'a -> 'a) -> 'a -> set -> 'a
    val partition : (item -> bool) -> set -> set * set
    val filter : (item -> bool) -> set -> set
    val exists : (item -> bool) -> set -> bool
    val find : (item -> bool) -> set -> item option
  end
end

structure ExternFunSymbol =
struct

  type id (= string)
  val touch : Symbol.longsymbol -> id
  val toString : id -> string
  val format_id : id -> SMLFormat.FormatExpression.expression list

  structure Map =
  struct
    structure Key =
    struct
      type ord_key = id
      val compare : ord_key * ord_key -> order
    end
    type 'a map (= boxed)
    val empty : 'a map
    val isEmpty : 'a map -> bool
    val singleton : Key.ord_key * 'a -> 'a map
    val insert : 'a map * Key.ord_key * 'a -> 'a map
    val insert' : (Key.ord_key * 'a) * 'a map -> 'a map
    val find : 'a map * Key.ord_key -> 'a option
    val lookup : 'a map * Key.ord_key -> 'a
    val inDomain : 'a map * Key.ord_key -> bool
    val remove : 'a map * Key.ord_key -> 'a map * 'a
    val first : 'a map -> 'a option
    val firsti : 'a map -> (Key.ord_key * 'a) option
    val numItems : 'a map -> int
    val listItems : 'a map -> 'a list
    val listItemsi : 'a map -> (Key.ord_key * 'a) list
    val listKeys : 'a map -> Key.ord_key list
    val collate : ('a * 'a -> order) -> 'a map * 'a map -> order
    val unionWith : ('a * 'a -> 'a) -> 'a map * 'a map -> 'a map
    val unionWithi : (Key.ord_key * 'a * 'a -> 'a) -> 'a map * 'a map -> 'a map
    val intersectWith : ('a * 'b -> 'c) -> 'a map * 'b map -> 'c map
    val intersectWithi : (Key.ord_key * 'a * 'b -> 'c) -> 'a map * 'b map -> 'c map
    val mergeWith : ('a option * 'b option -> 'c option) -> 'a map * 'b map -> 'c map
    val mergeWithi : (Key.ord_key * 'a option * 'b option -> 'c option) -> 'a map * 'b map -> 'c map
    val app : ('a -> unit) -> 'a map -> unit
    val appi : (Key.ord_key * 'a -> unit) -> 'a map -> unit
    val map : ('a -> 'b) -> 'a map -> 'b map
    val mapi : (Key.ord_key * 'a -> 'b) -> 'a map -> 'b map
    val foldl : ('a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val foldli : (Key.ord_key * 'a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val foldr : ('a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val foldri : (Key.ord_key * 'a * 'b -> 'b) -> 'b -> 'a map -> 'b
    val filter : ('a -> bool) -> 'a map -> 'a map
    val filteri : (Key.ord_key * 'a -> bool) -> 'a map -> 'a map
    val mapPartial : ('a -> 'b option) -> 'a map -> 'b map
    val mapPartiali : (Key.ord_key * 'a -> 'b option) -> 'a map -> 'b map
  end

  structure Set =
  struct
    structure Key =
    struct
      type ord_key = id
      val compare : ord_key * ord_key -> order
    end
    type item = Key.ord_key
    type set (= boxed)
    val empty : set
    val singleton : item -> set
    val fromList : item list -> set
    val add : set * item -> set
    val add' : item * set -> set
    val addList : set * item list -> set
    val delete : set * item -> set
    val member : set * item -> bool
    val isEmpty : set -> bool
    val equal : set * set -> bool
    val compare : set * set -> order
    val isSubset : set * set -> bool
    val numItems : set ->  int
    val listItems : set -> item list
    val union : set * set -> set
    val intersection : set * set -> set
    val difference : set * set -> set
    val map : (item -> item) -> set -> set
    val app : (item -> unit) -> set -> unit
    val foldl : (item * 'a -> 'a) -> 'a -> set -> 'a
    val foldr : (item * 'a -> 'a) -> 'a -> set -> 'a
    val partition : (item -> bool) -> set -> set * set
    val filter : (item -> bool) -> set -> set
    val exists : (item -> bool) -> set -> bool
    val find : (item -> bool) -> set -> item option
  end
end
